package com.gc.consumer;

import com.gc.common.JSONSerializer;
import com.gc.common.RpcDecoder;
import com.gc.common.RpcEncoder;
import com.gc.common.RpcRequest;
import com.gc.handler.UserClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;


import java.lang.reflect.Proxy;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RpcConsumer {

    //1、创建线程池对象   处理自定义事件
    //并且当前线程池的线程数以当前系统的cpu核数
    private static ExecutorService executor =
            Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    //2、声明一个自定义事件处理器  UserClientHandler
    private static UserClientHandler client;

    /**
     * 初始化客户端
     */
    private static void initClient() {
        //初始化 UserClientHandler
        client = new UserClientHandler();
        // 连接池
        EventLoopGroup group = new NioEventLoopGroup();
        //客户端引导对象
        Bootstrap b = new Bootstrap();
        //配置引导对象
        b.group(group)
                // Nio模式
                .channel(NioSocketChannel.class)
                //请求协议为TCP
                .option(ChannelOption.TCP_NODELAY, true)
                //监听handler 并初始化
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        //获取channelPipeline 管道
                        ChannelPipeline p = ch.pipeline();
                        //设置编码
                        p.addLast(new StringDecoder());
                        // p.addLast(new StringEncoder());
                        p.addLast(new RpcEncoder(RpcRequest.class, new JSONSerializer()));
//                        p.addLast(new RpcDecoder(RpcRequest.class,new JSONSerializer()));
                        //添加自定义事件处理器
                        p.addLast(client);
                    }
                });
        try {
            //异步连接服务
            b.connect("localhost", 8990).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建一个代理对象
     *
     * @param serviceClass
     * @return
     */
    public static Object createProxy(final Class<?> serviceClass) {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class<?>[]{serviceClass}, (proxy, method, args) -> {
                    if (client == null) {
                        initClient();
                    }
                    //  userClientHandler 设置参数
                    //通信协议对象
                    RpcRequest rpcRequest = new RpcRequest();
                    //类名
                    rpcRequest.setClassName(serviceClass.getName());
                    //方法名
                    rpcRequest.setMethodName(method.getName());
                    //参数
                    rpcRequest.setParameters(args);
                    //参数类型
                    rpcRequest.setParameterTypes(method.getParameterTypes());
                    //请求对象Id UUid 唯一Id
                    rpcRequest.setRequestId(UUID.randomUUID().toString());

                    client.setRpcRequest(rpcRequest);

                    return executor.submit(client).get();
                });
    }
}
